﻿#pragma once
#include "IResource.h"
#include "CRect.h"
#include "CColor.h"
#include <allegro5/allegro.h>
#include <allegro5\allegro_image.h>
#include "CSAllegroController.h"

namespace DarkStorm2D {
namespace GraphicsCore {

	//! Klasa reprezentująca Obraz.
	/*!
	 * 
	 */
	class  DLLDARKSTORM2D CImage : public IResource
	{
	protected:
		//! Obraz.
		ALLEGRO_BITMAP * m_Image;
		//! Kolor kluczowy na obrazie.
		CColor * m_ColorKey;
	public:
		//! Flagi dla Obrazów.
		enum EImageFlag {
			//! Obraz tworzony w pamięci karty graficznej.
			FLAG_IMAGE_VIDEO = ALLEGRO_VIDEO_BITMAP,
			//! Obraz tworzony w pamięci systemowej.
			FLAG_IMAGE_MEMORY = ALLEGRO_MEMORY_BITMAP,
		};
		CImage();
		/*!
		 * Tworzy obraz w pamięci karty graficznej.
		 * @param Width Szerokość tworzonej obrazu.
		 * @param Height Wysokość tworzonej obrazu.
		 * @param ColorKey Kolor kluczowy obrazu.
		 */
		CImage(int Width, int Height, CColor * ColorKey = NULL);
		/*!
		 * Tworzy obraz.
		 * @param Width Szerokość tworzonej obrazu.
		 * @param Height Wysokość tworzonej obrazu.
		 * @param Flag Flagi do tworzonego obrau.
		 * @param ColorKey Kolor kluczowy obrazu.
		 */
		CImage(int Width, int Height, int Flag, CColor * ColorKey = NULL);
		~CImage();

		/*!
		 * Tworzy nowy obraz w pamięci karty graficznej(Usuwa poprzedni).
		 * @param Width Szerokość tworzonej obrazu.
		 * @param Height Wysokość tworzonej obrazu.
		 * @param ColorKey Kolor kluczowy obrazu.
		 */
		bool Create(int Width, int Height, CColor * ColorKey = NULL);

		/*!
		 * Tworzy nowy obraz.(Usuwa poprzedni).
		 * @param Width Szerokość tworzonej obrazu.
		 * @param Height Wysokość tworzonej obrazu.
		 * @param ColorKey Kolor kluczowy obrazu.
		 */
		bool Create(int Width, int Height, int Flag = 0, CColor * ColorKey = NULL);

		virtual const CError& LoadFromFile(const std::string & Filename);

		//! Ładuje z pliku, można zdefiniować kolor kluczowy. 
		virtual const CError& LoadFromFile(const std::string & Filename, CColor * ColorKey = NULL);
	
		virtual const CError& Reload();

		void Fill(CColor * FillColor);
		//void FillRect(const CColor * FillColor, const CRect* FillRect);
		//void FillRect(const CColor * FillColor, int Left, int Top, int Right, int Bottom);

		inline void Draw(float x, float y, int Flags = 0)
		{
			al_draw_bitmap(m_Image,x,y,Flags);
		}
		inline void DrawRect(float x, float y, CRect* SrcRect, int Flags = 0)
		{
			al_draw_bitmap_region(m_Image,SrcRect->GetLeft(),SrcRect->GetTop(),SrcRect->GetRight(),SrcRect->GetBottom(),x,y,Flags);
		}
		inline void DrawRect(float x, float y, int Left, int Top, int Right, int Bottom, int Flags = 0)
		{
			al_draw_bitmap_region(m_Image,Left,Top,Right,Bottom,x,y,Flags);
		}
		//void DrawScale() = NULL;
		//void DrawRectScale() = NULL;
		//void DrawRotate() = NULL;
		//void DrawRectRotate() = NULL;
		//void DrawScaleRotate() = NULL;
		//void DrawRectScaleRotate() = NULL;

		inline void SetSize(int Width = 0, int Height = 0)
		{
			al_destroy_bitmap(m_Image);
			Create(Width,Height,al_get_bitmap_flags(m_Image));
			m_IsLoad = false;
		}

		/*!
		 * @return Szerokość obrazu.
		 */
		inline int GetWidth() 
		{
			return al_get_bitmap_width(m_Image);
		}
		/*!
		 * @return Wysokość Obrazu.
		 */
		inline int GetHeight() 
		{
			return al_get_bitmap_height(m_Image);
		}
		/*! Kopiuje Szerokość i wysokość obrazu do zmiennych z parametrów.
		 * @param Width Zmienna do której ma być skopiowana szerokość obrazu.
		 * @param Height Zmienna do której ma być skopiowana wysokość obrazu.
		 */
		inline void GetSize(int* Width, int* Height) 
		{
			 *Width  = al_get_bitmap_width(m_Image);
			 *Height = al_get_bitmap_height(m_Image);
		}
		/*!
		 * @Return Kolor kluczowy.
		 */
		inline const CColor& GetColorKey() const
		{
			return m_ColorKey;
		}

		/*!
		 * Niszczy obraz.
		 */
		void Destroy() 
		{ 
			if (m_Image != NULL) 
				al_destroy_bitmap(m_Image);
			m_Image = NULL; 
			if (m_ColorKey != NULL)
				delete m_ColorKey;
		}

	};

	//! Dla Smart Pointera.
	typedef boost::intrusive_ptr<CImage> ImagePtr;
};
};